home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / lib / flyEngine / flyBezier.cpp next >
Encoding:
C/C++ Source or Header  |  2000-12-15  |  15.2 KB  |  796 lines

  1. #include "../Fly3D.h"
  2.  
  3. float bezier_curve::distance(float *p,float *p1,float *p2)
  4. {
  5.     // returns distance from point p to line defined by p1,p2
  6.  
  7.     float dot=0,len1=0,len2=0;
  8.     int i;
  9.  
  10.     // alloc two vectors
  11.     float *v1=new float [nd];
  12.     float *v2=new float [nd];
  13.     
  14.     // compute length from (p1,p) and (p1,p2)
  15.     for( i=0;i<nd;i++ )
  16.     {
  17.         v1[i]= p[i]-p1[i];
  18.         v2[i]=p2[i]-p1[i];
  19.         len1+=v1[i]*v1[i];
  20.         len2+=v2[i]*v2[i];
  21.     }
  22.     len1=(float)sqrt(len1);
  23.     len2=(float)sqrt(len2);
  24.     
  25.     // normalize 
  26.     if (len1>0)
  27.         for( i=0;i<nd;i++ )
  28.             v1[i]/=len1;
  29.     if (len2>0)
  30.         for( i=0;i<nd;i++ )
  31.             v2[i]/=len2;
  32.     
  33.     // compute dot product
  34.     for( i=0;i<nd;i++ )
  35.         dot+=v1[i]*v2[i];
  36.  
  37.     // free vectors
  38.     delete v1; 
  39.     delete v2;
  40.  
  41.     // return distance
  42.     return (float)sqrt(len1*len1*(1.0f-dot*dot));
  43. }
  44.  
  45. int bezier_curve::adaptative_subdiv(float maxerror,float *points,int maxpoints)
  46. {
  47.     if (maxpoints<2) return 0;
  48.  
  49.     int npoints,i,j;
  50.     float tmp;
  51.  
  52.     // start points list with two points (the curve edges)
  53.     points[0]=0.0f;
  54.     points[1]=1.0f;
  55.     npoints=2;
  56.  
  57.     // subdiv curve recursevily
  58.     subdiv(0,1,&p[0],&p[nd*(np-1)],points,npoints,maxerror,maxpoints);
  59.  
  60.     // sort points
  61.     for( i=1;i<npoints;i++ )
  62.         for( j=i+1;j<npoints;j++ )
  63.             if (points[j]<points[i])
  64.             {
  65.                 tmp=points[i];
  66.                 points[i]=points[j];
  67.                 points[j]=tmp;
  68.             }
  69.  
  70.     // sort number of points
  71.     return npoints;
  72. }
  73.  
  74. void bezier_curve::subdiv(float u1,float u2,float *p1,float *p2,float *points,int& npoints,float maxerror,int maxpoints)
  75. {
  76.     // if points list is not full
  77.     if (npoints<maxpoints)
  78.     {
  79.     // alloc a new point
  80.     float *p=new float[nd];
  81.     
  82.     // compute segment midpoint coordinate
  83.     float u=(u1+u2)*0.5f;
  84.  
  85.     // evaluate curve at the segment midpoint
  86.     evaluate(u,p);
  87.  
  88.     // if error is bigger then maxerror
  89.     if (distance(p,p1,p2)>maxerror)
  90.         {
  91.         // add point to points list
  92.         points[npoints++]=u;
  93.         // subdiv each segment recursevily
  94.         subdiv(u1,u,p1,p,points,npoints,maxerror,maxpoints);
  95.         subdiv(u,u2,p,p2,points,npoints,maxerror,maxpoints);
  96.         }
  97.     
  98.     // delete allocated point
  99.     delete p;
  100.     }
  101. }
  102.  
  103. void bezier_curve::reset()
  104. {
  105.     if (p) 
  106.         delete p;
  107.     p=0;
  108.     ns=0;
  109.     np=0;
  110. }
  111.  
  112. void bezier_curve::set_dim(int ndim)
  113. {
  114.     reset();
  115.     nd=ndim;
  116. }
  117.  
  118. void bezier_curve::add_point(float *f)
  119. {
  120.     // adds a new point to the curve
  121.     // f must point to nd floats
  122.  
  123.     if (nd==0) return;
  124.     float *t=new float[(np+1)*nd];
  125.     if (p!=0)
  126.         {
  127.          memcpy(t,p,sizeof(float)*np*nd);
  128.          delete p;
  129.         }
  130.     p=t;
  131.     memcpy(&p[np*nd],f,sizeof(float)*nd);
  132.     np++;
  133.     if (((np-4)%3)==0 && np>1)
  134.        ns++;
  135. }
  136.  
  137. void bezier_curve::evaluate_tangent(float u,float *f)
  138. {    
  139.     // evaluate the curve tangent at position u
  140.     // f must point to nd floats
  141.  
  142.     if (p==0) return;
  143.  
  144.     static float B[4];
  145.     float u1,u2;
  146.     int s,a,b,c;
  147.  
  148.     if (u==1.0f)
  149.         s=np-4;
  150.     else s=(int)(u*(np-1))/3*3;
  151.     u1=(u-(float)s/(np-1))*ns;
  152.  
  153.     u2=u1*u1;
  154.     B[0] =-3.0f +  6.0f*u1 - 3.0f*u2;
  155.     B[1] = 3.0f - 12.0f*u1 + 9.0f*u2;
  156.     B[2] = 6.0f*u1 - 9.0f*u2;
  157.     B[3] = 3.0f*u2;
  158.  
  159.     memset(f,0,sizeof(float)*nd);
  160.  
  161.     c=s*nd;
  162.     for( a=0;a<4;a++ )
  163.         for( b=0;b<nd;b++ )
  164.             f[b]+=p[c++]*B[a];
  165. }
  166.  
  167. void bezier_curve::evaluate(float u,float *f)
  168. {
  169.     // evaluate the curve point at position u
  170.     // f must point to nd floats
  171.  
  172.     if (p==0) return;
  173.  
  174.     static float B[4];
  175.     float u1,u2;
  176.     int s,a,b,c;
  177.  
  178.     if (u==1.0f)
  179.         s=np-4;
  180.     else s=(int)(u*(np-1))/3*3;
  181.     u1=(u-(float)s/(np-1))*ns;
  182.  
  183.     u2=1.0f-u1;
  184.     B[0]=u2*u2*u2;
  185.     B[1]=3.0f*u1*u2*u2;
  186.     B[2]=3.0f*u1*u1*u2;
  187.     B[3]=u1*u1*u1;
  188.  
  189.     memset(f,0,sizeof(float)*nd);
  190.  
  191.     c=s*nd;
  192.     for( a=0;a<4;a++ )
  193.         for( b=0;b<nd;b++ )
  194.             f[b]+=p[c++]*B[a];
  195. }
  196.  
  197. int bezier_curve::load_bez(char *file)
  198. {
  199.     // loads the curve from a .bez text file
  200.  
  201.     fly_pak fp;
  202.     if (!fp.open(file))
  203.         return 0;
  204.  
  205.     reset();
  206.     int i,j,n,d;
  207.     float *f;
  208.     
  209.     pivot.x=fp.get_float();
  210.     pivot.y=fp.get_float();
  211.     pivot.z=fp.get_float();
  212.     d=fp.get_int();
  213.     n=fp.get_int();
  214.     set_dim(d);
  215.     f=new float[d];
  216.     for( i=0;i<n;i++ )
  217.         {
  218.         for( j=0;j<d;j++ )
  219.             f[j]=fp.get_float();
  220.         add_point(f);
  221.         }
  222.     delete f;
  223.     fp.close();
  224.     return 1;
  225. }
  226.  
  227. float bezier_curve::length()
  228. {
  229.     if (ns==0 || nd==0) return 0;
  230.  
  231.     int i,j=ns*8,k,vv=1;
  232.     float *v[2],len=0.0f,f;
  233.     v[0]=new float[nd];
  234.     v[1]=new float[nd];
  235.     evaluate(0.0f,v[0]);
  236.     for( i=1;i<j;i++ )
  237.     {
  238.         evaluate((float)i/(j-1),v[vv]);
  239.         f=0.0f;
  240.         for( k=0;k<nd;k++ )
  241.             f+=(v[0][k]-v[1][k])*(v[0][k]-v[1][k]);
  242.         len+=(float)sqrt(f);
  243.         vv=!vv;
  244.     }
  245.  
  246.     delete v[0];
  247.     delete v[1];
  248.  
  249.     return len;
  250. }
  251.  
  252. void bezier_patch::build_loft(bezier_curve *shape,bezier_curve *path,int texture,int lightmap,float tileu,float tilev)
  253. {
  254.     reset();
  255.     if (shape && path && shape->nd==3 && path->nd==3)
  256.     {
  257.     mode=4;
  258.     texpic=texture;
  259.     lm=lightmap;
  260.     npu=shape->np;
  261.     npv=path->np;
  262.     np=npu*npv;
  263.     nsu=shape->ns;
  264.     nsv=path->ns;
  265.     p=new vector[np];
  266.     t=new vector[np];
  267.     vector v;
  268.     local_system ls;
  269.     int i,j,k=0;
  270.     ls.align_z(vector(0,0,1));
  271.     for( j=0;j<npv;j++ )
  272.         {
  273.         path->evaluate_tangent((float)j/(npv-1),&v.x);
  274.         v.normalize();
  275.         ls.rotate(ls.Z,v);
  276.         v=*((vector *)&path->p[j*3]);
  277.         for( i=0;i<npu;i++ )
  278.             {
  279.             p[k]=v+(*((vector *)&shape->p[i*3])*ls.mat);
  280.             t[k].x=(float)i/(npu-1)*tileu;
  281.             t[k].y=(float)j/(npv-1)*tilev;
  282.             t[k].z=(float)i/(npu-1);
  283.             t[k].w=(float)j/(npv-1);
  284.             k++;
  285.             }
  286.         }
  287.     }
  288. }
  289.  
  290. void bezier_patch::evaluate(int evaltype,float u,float v,vector *dest)
  291. {
  292.     if (p==0 || t==0) 
  293.         return;
  294.  
  295.     static float Bu[4],Bv[4],Bdu[4],Bdv[4];
  296.     float u1,u2,v1,v2,f;
  297.     int i,j,k,su,sv;
  298.  
  299.     vector point(0,0,0);
  300.     vector textcoord(0,0,0,0);
  301.     vector du(0,0,0),dv(0,0,0);
  302.  
  303.     switch(mode)
  304.     {
  305.     case 3:
  306.         if (FP_BITS(u)==FP_ONE_BITS)
  307.             su=npu-3;
  308.         else su=(int)(u*(npu-1))/2*2;
  309.         u1=(u-(float)su/(npu-1))*nsu;
  310.  
  311.         if (FP_BITS(v)==FP_ONE_BITS)
  312.             sv=npv-3;
  313.         else sv=(int)(v*(npv-1))/2*2;
  314.         v1=(v-(float)sv/(npv-1))*nsv;
  315.  
  316.         u2=1.0f-u1;
  317.         Bu[0]=u2*u2;
  318.         Bu[1]=2.0f*u1*u2;
  319.         Bu[2]=u1*u1;
  320.  
  321.         v2=1.0f-v1;
  322.         Bv[0]=v2*v2;
  323.         Bv[1]=2.0f*v1*v2;
  324.         Bv[2]=v1*v1;
  325.  
  326.         if (evaltype&PATCH_EVAL_NORMAL)
  327.             {
  328.             Bdu[0]= 2.0f*u1-2.0f;
  329.             Bdu[1]= 2.0f-4.0f*u1;
  330.             Bdu[2]= 2.0f*u1;
  331.  
  332.             Bdv[0]= 2.0f*v1-2.0f;
  333.             Bdv[1]= 2.0f-4.0f*v1;
  334.             Bdv[2]= 2.0f*v1;
  335.             }
  336.         break;
  337.     case 4:
  338.         if (FP_BITS(u)==FP_ONE_BITS)
  339.             su=npu-4;
  340.         else su=(int)(u*(npu-1))/3*3;
  341.         u1=(u-(float)su/(npu-1))*nsu;
  342.  
  343.         if (FP_BITS(v)==FP_ONE_BITS)
  344.             sv=npv-4;
  345.         else sv=(int)(v*(npv-1))/3*3;
  346.         v1=(v-(float)sv/(npv-1))*nsv;
  347.  
  348.         u2=1.0f-u1;
  349.         Bu[0]=u2*u2*u2;
  350.         Bu[1]=3.0f*u1*u2*u2;
  351.         Bu[2]=3.0f*u1*u1*u2;
  352.         Bu[3]=u1*u1*u1;
  353.  
  354.         v2=1.0f-v1;
  355.         Bv[0]=v2*v2*v2;
  356.         Bv[1]=3.0f*v1*v2*v2;
  357.         Bv[2]=3.0f*v1*v1*v2;
  358.         Bv[3]=v1*v1*v1;
  359.  
  360.         if (evaltype&PATCH_EVAL_NORMAL)
  361.             {
  362.             u2=u1*u1;
  363.             Bdu[0]=-3.0f +  6.0f*u1 - 3.0f*u2;
  364.             Bdu[1]= 3.0f - 12.0f*u1 + 9.0f*u2;
  365.             Bdu[2]= 6.0f*u1 - 9.0f*u2;
  366.             Bdu[3]= 3.0f*u2;
  367.  
  368.             v2=v1*v1;
  369.             Bdv[0]=-3.0f +  6.0f*v1 - 3.0f*v2;
  370.             Bdv[1]= 3.0f - 12.0f*v1 + 9.0f*v2;
  371.             Bdv[2]= 6.0f*v1 - 9.0f*v2;
  372.             Bdv[3]= 3.0f*v2;
  373.             }
  374.     }
  375.  
  376.     for( i=0;i<mode;i++ )
  377.         for( j=0;j<mode;j++ )
  378.         {
  379.             k=(sv+j)*npu+su+i;
  380.             f=Bu[i]*Bv[j];
  381.             if (evaltype&PATCH_EVAL_POINT)
  382.                 {
  383.                 point.x+=f*p[k].x;
  384.                 point.y+=f*p[k].y;
  385.                 point.z+=f*p[k].z;
  386.                 }
  387.             if (evaltype&PATCH_EVAL_TEXTCOORD)
  388.                 {
  389.                 textcoord.x+=f*t[k].x;
  390.                 textcoord.y+=f*t[k].y;
  391.                 textcoord.z+=f*t[k].z;
  392.                 textcoord.w+=f*t[k].w;
  393.                 }
  394.             if (evaltype&PATCH_EVAL_NORMAL)
  395.                 {
  396.                 du+=p[k]*(Bdu[i]*Bv[j]);
  397.                 dv+=p[k]*(Bu[i]*Bdv[j]);
  398.                 }
  399.         }
  400.  
  401.     if (evaltype&PATCH_EVAL_POINT)
  402.         *(dest++)=point;
  403.     if (evaltype&PATCH_EVAL_TEXTCOORD)
  404.         *(dest++)=textcoord;
  405.     if (evaltype&PATCH_EVAL_NORMAL)
  406.         {
  407.         dest->cross(dv,du);
  408.         dest->normalize();
  409.         }
  410. }
  411.  
  412. void bezier_patch::reset()
  413. {
  414.     if (p) 
  415.         delete p;
  416.     p=0;
  417.     if (t)
  418.         delete t;
  419.     t=0;
  420.     if (surf)
  421.         delete surf;
  422.     surf=0;
  423.     np=npu=npv=nsu=nsv=0;
  424.     mode=0;
  425.     levelu=0;
  426.     levelv=0;
  427.     nvertu=0;
  428.     nvertv=0;
  429. }
  430.  
  431. int bezier_patch::load_pch(char *file)
  432. {
  433.     reset();
  434.  
  435.     fly_pak fp;
  436.     if (!fp.open(file))
  437.         return 0;
  438.  
  439.     mode=3;
  440.  
  441.     char texture[256];
  442.     fp.get_string(texture);
  443.     texpic=flyengine->get_picture(texture);
  444.  
  445.     int lm_pic=fp.get_int();
  446.     int lm_offsetx=fp.get_int();
  447.     int lm_offsety=fp.get_int();
  448.     int lm_sizex=fp.get_int();
  449.     int lm_sizey=fp.get_int();
  450.     lm=-1;
  451.     if (lm_pic<flyengine->nlmpic)
  452.         {
  453.         flyengine->lm[flyengine->nlm]=new light_map(-1,lm_pic,lm_offsetx,lm_offsety,lm_sizex,lm_sizey,3);
  454.         flyengine->fm[flyengine->nlm]=new light_map(-1,lm_pic,lm_offsetx,lm_offsety,lm_sizex,lm_sizey,4);
  455.         lm=flyengine->nlm++;
  456.         }
  457.  
  458.     npu=fp.get_int();
  459.     npv=fp.get_int();
  460.  
  461.     pivot.x=fp.get_float();
  462.     pivot.y=fp.get_float();
  463.     pivot.z=fp.get_float();
  464.  
  465.     np=npu*npv;
  466.     nsu=(npu-1)/2;
  467.     nsv=(npv-1)/2;
  468.  
  469.     p=new vector[np];
  470.     t=new vector[np];
  471.     
  472.     int i;
  473.     for( i=0;i<np;i++ )
  474.     {
  475.         p[i].x=fp.get_float();
  476.         p[i].y=fp.get_float();
  477.         p[i].z=fp.get_float();
  478.  
  479.         t[i].x=fp.get_float();
  480.         t[i].y=fp.get_float();
  481.         t[i].z=fp.get_float();
  482.         t[i].w=fp.get_float();
  483.     }
  484.  
  485.     fp.close();
  486.     return 1;
  487. }
  488.  
  489. int find_subdiv_level(vector v0,vector v1,vector v2)
  490. {
  491.     int level;
  492.     vector a, b, dist;
  493.     
  494.     float factor=flyengine->curveerr*flyengine->curveerr;
  495.  
  496.     for (level=0;level<8;level++)
  497.     {
  498.     a=(v0+v1)*0.5f;
  499.     b=(v1+v2)*0.5f;
  500.     v2=(a+b)*0.5f;
  501.  
  502.     dist=v2-v1;
  503.     if (vec_dot(dist,dist)<factor)
  504.         break;
  505.     v1=a;
  506.     }
  507.  
  508.     return level;
  509. }
  510.  
  511.  
  512.  
  513. void bezier_patch::build_surface()
  514. {
  515.     if (mode!=3 || p==0 || t==0)
  516.         return;
  517.     int i,j,k,a;
  518.     vector normal;
  519.  
  520.     levelu=0;
  521.     levelv=0;
  522.     k=0;
  523.     for( j=0;j<=nsv;j++,k+=npu-1 )
  524.     for( i=0;i<=nsu;i++,k+=2 )
  525.     {
  526.         if (i<nsu)
  527.         {
  528.             a=find_subdiv_level(p[k],p[k+1],p[k+2]);
  529.             if (a>levelu)
  530.                 levelu=a;
  531.         }
  532.         if (j<nsv)
  533.         {
  534.             a=find_subdiv_level(p[k],p[k+npu],p[k+2*npu]);
  535.             if (a>levelv)
  536.                 levelv=a;
  537.         }
  538.     }
  539.  
  540.     nvertu=(1<<levelu)*nsu+1;
  541.     nvertv=(1<<levelv)*nsv+1;
  542.     if (nvertu<2) nvertu=2;
  543.     if (nvertv<2) nvertv=2;
  544.  
  545.     if (surf) delete surf;
  546.     surf=new vector[nvertu*nvertv*2];
  547.  
  548.     k=0;
  549.     for( j=0;j<nvertv;j++ )
  550.         for( i=0;i<nvertu;i++,k+=2 )
  551.             evaluate(PATCH_EVAL_POINT|PATCH_EVAL_TEXTCOORD,
  552.                 (float)i/(nvertu-1),(float)j/(nvertv-1),&surf[k]);
  553. }
  554.  
  555. void bezier_patch::illuminate(vector& p,float rad,vector& color,int shadows)
  556. {
  557.     if (lm==-1)
  558.         return;
  559.  
  560.     int i,j,k;
  561.     float dist,u,v;
  562.     vector point,dir;
  563.  
  564.     // get lightmap applied to patch
  565.     light_map *l=flyengine->lm[lm];
  566.     unsigned char *uc;
  567.  
  568.     rad*=rad;
  569.     // for each lightmap pixel in y
  570.     for( j=0;j<l->sizey;j++ )
  571.     {
  572.         uc=&l->bmp[j*l->bytesx];
  573.         v=(j+0.5f)/l->sizey;
  574.         // for each lightmap pixel in x
  575.         for( i=0;i<l->sizex;i++ )
  576.         {
  577.         u=(i+0.5f)/l->sizex;
  578.  
  579.         // get lightmap pixel position in the patch surface
  580.         evaluate(PATCH_EVAL_POINT,u,v,&point);
  581.         
  582.         // check if point is inside light radius
  583.         dir=p-point;
  584.         dist=vec_dot(dir,dir);
  585.         if (dist>rad)
  586.             uc+=3;
  587.         else 
  588.             {
  589.             // compute lighting factor based on light radius and pixel distance
  590.             dist=(1.0f-dist/rad)*255.0f;
  591.  
  592.             // apply colors to lightmap
  593.             k=(int)(color.x*dist)+(int)(*uc);
  594.             *(uc++)=k>255?255:k;
  595.  
  596.             k=(int)(color.y*dist)+(int)(*uc);
  597.             *(uc++)=k>255?255:k;
  598.  
  599.             k=(int)(color.z*dist)+(int)(*uc);
  600.             *(uc++)=k>255?255:k;
  601.             }
  602.         }
  603.     }
  604.     
  605.     l->lastupdate=flyengine->cur_step;
  606. }
  607.  
  608. void bezier_patch::draw(int nleveldrop)
  609. {
  610.     if (surf==0)
  611.         return;
  612.  
  613.     int i,j,k,l,mapcount=0;
  614.     float *f1,*f2;
  615.     int dropu,dropv,numstrips;
  616.  
  617.     if (levelu>=nleveldrop)
  618.         dropu=nleveldrop;
  619.     else dropu=levelu;
  620.     if (levelv>=nleveldrop)
  621.         dropv=nleveldrop;
  622.     else dropv=levelv;
  623.     numstrips=(1<<(levelv-dropv))*nsv;
  624.     dropu=(1<<dropu);
  625.     dropv=(1<<dropv);
  626.     k=dropu*8;
  627.     l=dropv*nvertu*2;
  628.  
  629.     glColor3ub(255,255,255);
  630.  
  631.     if (flyengine->multitexture && ntextureunits>1 && flyengine->nlm)
  632.         {
  633.         tc->use(texpic);
  634.         if (lm!=-1)
  635.             tc->use(flyengine->lm[lm]->pic+flyengine->lmbase,1);
  636.         for( j=0;j<numstrips;j++ )
  637.             {
  638.             f1=(float * )&surf[j*l]; f2=f1+(l<<2);
  639.             glBegin(GL_TRIANGLE_STRIP);
  640.             for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
  641.                 {
  642.                 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,f2+4);
  643.                 glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,f2+6);
  644.                 glVertex3fv(f2);
  645.                 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,f1+4);
  646.                 glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,f1+6);
  647.                 glVertex3fv(f1);
  648.                 }
  649.             glEnd();
  650.             }
  651.         tc->use(-1,1);
  652.         tc->use(-1,0);
  653.         mapcount+=2;
  654.         }
  655.     else
  656.     {
  657.     if (flyengine->mapmode&MAPPING_TEXTURE)
  658.         {
  659.         tc->use(texpic);
  660.         for( j=0;j<numstrips;j++ )
  661.             {
  662.             f1=(float * )&surf[j*l]; f2=f1+(l<<2);
  663.             glBegin(GL_TRIANGLE_STRIP);
  664.             for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
  665.                 {
  666.                 glTexCoord2fv(f2+4);
  667.                 glVertex3fv(f2);
  668.                 glTexCoord2fv(f1+4);
  669.                 glVertex3fv(f1);
  670.                 }
  671.             glEnd();
  672.             }
  673.         mapcount++;
  674.         }
  675.  
  676.     if (flyengine->mapmode&MAPPING_DETAIL &&
  677.         flyengine->detailpic!=-1)
  678.         {
  679.         if (mapcount)
  680.             {
  681.             glBlendFunc(GL_ZERO,GL_SRC_COLOR);
  682.             glDepthMask(GL_FALSE);
  683.             glDepthFunc(GL_EQUAL);
  684.             }
  685.         tc->use(flyengine->detailpic);
  686.         for( j=0;j<numstrips;j++ )
  687.             {
  688.             f1=(float * )&surf[j*l]; f2=f1+(l<<2);
  689.             glBegin(GL_TRIANGLE_STRIP);
  690.             for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
  691.                 {
  692.                 glTexCoord2f(f2[4]*flyengine->detailtile,f2[5]*flyengine->detailtile);
  693.                 glVertex3fv(f2);
  694.                 glTexCoord2f(f1[4]*flyengine->detailtile,f1[5]*flyengine->detailtile);
  695.                 glVertex3fv(f1);
  696.                 }
  697.             glEnd();
  698.             }
  699.         mapcount++;
  700.         }
  701.  
  702.     if (flyengine->mapmode&MAPPING_LIGHTMAP &&
  703.         flyengine->nlm!=0)
  704.         {
  705.         if (mapcount)
  706.             {
  707.             glBlendFunc(GL_ZERO,GL_SRC_COLOR);
  708.             glDepthMask(GL_FALSE);
  709.             glDepthFunc(GL_EQUAL);
  710.             }
  711.         tc->use(flyengine->lm[lm]->pic+flyengine->lmbase);
  712.         for( j=0;j<numstrips;j++ )
  713.             {
  714.             f1=(float * )&surf[j*l]; f2=f1+(l<<2);
  715.             glBegin(GL_TRIANGLE_STRIP);
  716.             for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
  717.                 {
  718.                 glTexCoord2fv(f2+6);
  719.                 glVertex3fv(f2);
  720.                 glTexCoord2fv(f1+6);
  721.                 glVertex3fv(f1);
  722.                 }
  723.             glEnd();
  724.             }
  725.         mapcount++;
  726.         }
  727.     }
  728.  
  729.     if (flyengine->mapmode&MAPPING_FOGMAP)
  730.     if (flyengine->nlm!=0)
  731.         {
  732.         if (mapcount)
  733.             {
  734.             glDepthMask(GL_FALSE);
  735.             glDepthFunc(GL_EQUAL);
  736.             glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  737.             }
  738.         tc->use(flyengine->lm[lm]->pic+flyengine->fmbase);
  739.         for( j=0;j<numstrips;j++ )
  740.             {
  741.             f1=(float * )&surf[j*l]; f2=f1+(l<<2);
  742.             glBegin(GL_TRIANGLE_STRIP);
  743.             for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
  744.                 {
  745.                 glTexCoord2fv(f2+6);
  746.                 glVertex3fv(f2);
  747.                 glTexCoord2fv(f1+6);
  748.                 glVertex3fv(f1);
  749.                 }
  750.             glEnd();
  751.             }
  752.         mapcount++;
  753.         }
  754.  
  755.     glDepthMask(GL_TRUE);
  756.     glDepthFunc(GL_LESS);
  757.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  758. }
  759.  
  760. mesh *bezier_patch::build_mesh()
  761. {
  762.     int i,j,k;
  763.     
  764.     mesh *m=new mesh;
  765.     
  766.     m->nv=nvertu*nvertv;
  767.     m->vert=new vector[m->nv];
  768.     k=0;
  769.     for( i=0;i<m->nv;i++,k+=2 )
  770.         m->vert[i]=surf[k];
  771.  
  772.     m->nf=(nvertu-1)*(nvertv-1)*2;
  773.     m->localfaces=new face[m->nf];
  774.     m->faces=new face *[m->nf];
  775.     k=0;
  776.     for( j=0;j<nvertv-1;j++ )
  777.     for( i=0;i<nvertu-1;i++ )
  778.     {
  779.         m->localfaces[k].color.vec(1,1,1,1);
  780.         m->localfaces[k].vert[0]=&m->vert[j*nvertu+i];
  781.         m->localfaces[k].vert[1]=&m->vert[j*nvertu+i+1];
  782.         m->localfaces[k].vert[2]=&m->vert[(j+1)*nvertu+i+1];
  783.         m->faces[k]=&m->localfaces[k];
  784.         k++;
  785.         m->localfaces[k].color.vec(1,1,1,1);
  786.         m->localfaces[k].vert[0]=&m->vert[j*nvertu+i];
  787.         m->localfaces[k].vert[1]=&m->vert[(j+1)*nvertu+i+1];
  788.         m->localfaces[k].vert[2]=&m->vert[(j+1)*nvertu+i];
  789.         m->faces[k]=&m->localfaces[k];
  790.         k++;
  791.     }
  792.  
  793.     m->compute_normals(MESH_FACENORM|MESH_VERTNORM|MESH_BBOX);
  794.  
  795.     return m;
  796. }